package progressbar

import (
	"time"
)

const _DEFAULT_WINDOW_SIZE = 2 * time.Second

type (
	// SpeedCalculator 定义速度计时器的数据结构
	SpeedCalculator struct {
		windowSize time.Duration // 时间窗口 (推荐1-3秒)
		lastSpeed  float64       // 缓存的上次速度
		samples    []speedSample // 采集的样本集
	}

	// speedSample 定义速度样本点的数据结构
	speedSample struct {
		timestamp time.Time
		progress  int
	}
)

func NewSpeedCalculator(window ...time.Duration) *SpeedCalculator {
	calculator := &SpeedCalculator{windowSize: _DEFAULT_WINDOW_SIZE, samples: make([]speedSample, 0)}
	if len(window) > 0 {
		calculator.windowSize = window[0]
	}

	return calculator
}

func (own *SpeedCalculator) Update(current int) float64 {
	now := time.Now()

	// 添加新样本
	own.samples = append(own.samples, speedSample{
		timestamp: now,
		progress:  current,
	})

	// 清理过期样本
	cutoff := now.Add(-own.windowSize)
	for len(own.samples) > 0 && own.samples[0].timestamp.Before(cutoff) {
		own.samples = own.samples[1:]
	}

	// 计算窗口内速度
	if len(own.samples) < 2 {
		return own.lastSpeed // 样本不足时返回上次速度
	}

	deltaProgress := current - own.samples[0].progress
	deltaTime := now.Sub(own.samples[0].timestamp).Seconds()

	currentSpeed := 0.0
	if deltaTime > 0 {
		currentSpeed = float64(deltaProgress) / deltaTime
	}

	// 应用指数平滑 (α=0.7)
	own.lastSpeed = 0.7*currentSpeed + 0.3*own.lastSpeed
	return own.lastSpeed
}
